-- Based on haste's oCD (http://ixo.no/git/)

local timers = {}
local list = {}

local class = CreateFrame"Cooldown"
local mt = {__index = class, __call = function(self, ...) self:update(...) end}

local GetTime = GetTime
local string_format = string.format
local math_fmod = math.fmod
local math_floor = math.floor

-- Settings:
local min, max, growth

local formatTime = function(time)
	local m, s, text
	if(time < 0) then
		return
	elseif(time < 10) then
		text = string_format("%.1f", time)
	else
		m = math_floor(time / 60)
		s = math_fmod(time, 60)
		text = (m == 0 and string_format("%d", s)) or string_format("%d:%02d", m, s)
	end

	return text
end

local sort = function(a, b)
	return a.max > b.max
end

-- TODO: Create a frame we can move around.
local updatePosition = function()
	table.sort(list, sort)

	local prev
	for _, obj in ipairs(list) do
		obj:ClearAllPoints()
			obj:SetHeight(raidcd.db.size)
			obj:SetWidth(raidcd.db.size)
		if(prev) then
			obj:SetPoint("TOP", prev, "BOTTOM")
		else
			obj:SetPoint("LEFT", RaidCDFrame, 5, 50)
		end

		prev = obj
	end
end

-- TODO: Remove the global reference to these table.
raidcd.list = list
raidcd.timers = timers
raidcd.rcd = rcd
raidcd.pos = updatePosition

local now, time
local OnUpdate = function(self, elapsed)
	self.time = self.time + elapsed
	if(self.time > .03) then
		now = self.max-GetTime()
		if(now >= 0) then
			time = formatTime(now)
			self.value:SetText(self.player.." ("..time..")")

			if(time == "3.0") then self.value:SetTextColor(.8, .1, .1) end
		else
			self:update(0)
		end
	
		self.time = 0
	end
end

function class.CreateMainFrame()
	local f = CreateFrame("Frame","RaidCDFrame",UIParent)
	f:SetFrameStrata("BACKGROUND")
	f:SetWidth(250)  -- Set These to whatever height/width is needed
	f:SetHeight(150) -- for your Texture
	f:SetMovable(true)
	f:EnableMouse(true)
	f:RegisterForDrag("LeftButton")
	f:SetScript("OnDragStart", function() if IsAltKeyDown() then this:StartMoving() end end)
	f:SetScript("OnDragStop", function() this:StopMovingOrSizing() raidcd:savePosition() end)

	f:SetBackdrop({
        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16,
	})
	f:SetBackdropColor(0, 0, 0, .5)

	local text = f:CreateFontString(nil, "OVERLAY")
	text:SetFont(STANDARD_TEXT_FONT, 15, "OUTLINE")

	text:SetText"RaidCD"
	text:Show()
	text:SetPoint("BOTTOM", f, "TOP", 0, 0)


	f:SetPoint("CENTER",0,0)
	f:Hide()

	raidcd.frame = f
end


local new = function(name, spellid, player)
	local sb = setmetatable(CreateFrame"Cooldown", mt)
	local texture = select(3, GetSpellInfo(tostring(spellid)))
	sb:Hide()

	sb.player = player
	sb.name = name
	sb.time = 0

	sb.spellid = spellid

	sb:SetParent(UIParent)
	sb:SetHeight(raidcd.db.size)
	sb:SetWidth(raidcd.db.size)
	sb:SetScript("OnUpdate", OnUpdate)

	local icon = sb:CreateTexture(nil, "BACKGROUND")
	icon:SetTexture(texture)
	icon:SetAllPoints(sb)
	icon:SetAlpha(.6)

	local text = sb:CreateFontString(nil, "OVERLAY")
	text:SetFont(STANDARD_TEXT_FONT, raidcd.db.size-15, "OUTLINE")

	sb.value = text
	sb.icon = icon
	
	return sb
end

-- TODO: Add grouping here:
function class.register(name, spellid, player)
	if(timers[player.."_"..name]) then return end
	timers[player.."_"..name] = new(name, spellid, player)

	return timers[name]
end

function class:update(duration, time)
	if(duration == 0 and self:IsShown()) then
		self:Hide()

		for k, v in ipairs(list) do
			if(v == self) then
				table.remove(list, k)
			end
		end

		updatePosition()
	elseif(duration > min and duration < max and not self:IsShown()) then
		self.max = time + duration
		self:SetCooldown(time, duration)

		table.insert(list, self)
		updatePosition()

		if(duration > 3) then self.value:SetTextColor(1, 1, 1) end
	end
end

function class.setMinMax(mincd, maxcd)
	min, max = mincd, maxcd
end

local anchors = {
	top		= "BOTTOM#TOP#0#0",
	bottom	= "TOP#BOTTOM#0#0",

	left	= "RIGHT#LEFT#-3#-1",
	right	= "LEFT#RIGHT#3#-1",

	center	= "CENTER#CENTER#0#-1",
}

function class.setTextPosition(pos, x2, y2)
	local p1, p2, x, y = strsplit("#", anchors[pos])

	if(x2 and type(x2) == "number") then x = x + x2 end
	if(y2 and type(y2) == "number") then y = y + y2 end

	if(pos == "hidden") then
		for _, obj in pairs(timers) do
			obj.value:Hide()
		end
	else
		for _, obj in pairs(timers) do
			obj.value:Show()
			obj.value:SetPoint(p1, obj, p2, x, y)
		end
	end

end

raidcd.bars = class

